#ifndef threading_Thread_H
#define threading_Thread_H

#ifndef WIN32
# include <pthread.h>
#endif

namespace serika
{
	namespace ut
	{
		struct TimeVal;
	}

	namespace threading
	{
	#ifdef WIN32
		extern unsigned long __stdcall ThreadFunc(void*);
	#else
		extern void* ThreadFunc(void*);
	#endif
	
		class Thread
		{
		public:
			Thread();
			virtual ~Thread();
	
			virtual void Run() = 0;
	
			bool Start();
			void Join();
	
	#ifdef WIN32
			typedef unsigned long ID;
	#else
			typedef pthread_t ID;
	#endif
			ID GetThreadId() const;
			static ID GetCurrentThreadId();
			bool IsStarted() const { return mStarted; }
	
			bool operator==(const Thread&) const;
			bool operator!=(const Thread&) const;
	
			static void Sleep(const ut::TimeVal&);
			static void Sleep(unsigned long milliseconds);
			static void SchedYield();	// yields the processor to another thread
		protected:
			bool mStarted;
	
	#ifdef _WIN32
			void* mHandle;
			unsigned long  mId;
	#else
			pthread_t mThread;
	#endif
	
		private:
			Thread(const Thread&);              // Copying is forbidden
			void operator=(const Thread&);      // Assignment is forbidden
	
	#ifdef WIN32
			friend unsigned long __stdcall ThreadFunc(void*);
	#else
			friend void* ThreadFunc(void*);
	#endif
		};
	}
}

#endif
